/**
 * @ClassName:
 * @author:
 * @Description:
 * @Date
 **/
//希尔排序
public class HillSort {
    private HillSort() {
    }

    public static <E extends Comparable<E>> void sort(E[] data) {
        int h = data.length / 2;//每次元素的间距
        while (h >= 1) {
            for (int start = 0; start < h; start++) {
                //对data[start,start+h,start+2h,start+3h...]，进行插入排序
                //第一次元素间距为数组长度的一半，然后每次循环间距缩短为原来的1/2
                for (int i = start + h; i < data.length; i += h) {
                    //暂存一下
                    E t = data[i];
                    int j;
                    for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) {
                        data[j] = data[j - h];
                    }
                    data[j] = t;
                }
            }
            h /= 2;
        }
    }

    public static <E extends Comparable<E>> void sort2(E[] data) {
        int h = data.length / 2;//每次元素的间距
        while (h >= 1) {
            //对data[start,start+h,start+2h,start+3h...]，进行插入排序
            //第一次元素间距为数组长度的一半，然后每次循环间距缩短为原来的1/2
            for (int i = h; i < data.length; i++) {
                //暂存一下
                E t = data[i];
                int j;
                for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) {
                    data[j] = data[j - h];
                }
                data[j] = t;
            }
            h /= 2;
        }
    }

    public static <E extends Comparable<E>> void sort3(E[] data) {
        int h = 1;//每次元素的间距
        //新的步长序列
        while (h < data.length) {
            h = h * 3 + 1;
        }
        while (h >= 1) {
            //对data[start,start+h,start+2h,start+3h...]，进行插入排序
            //第一次元素间距为数组长度的一半，然后每次循环间距缩短为原来的1/2
            for (int i = h; i < data.length; i++) {
                //暂存一下
                E t = data[i];
                int j;
                for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) {
                    data[j] = data[j - h];
                }
                data[j] = t;
            }
            h /= 3;
        }
    }
}
